package com.sx.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.sx.core.model.Information;
import com.sx.core.mybatis.SessionTemplate;
import com.sx.core.utils.JwtUtils;
import com.sx.core.utils.PropertyUtils;
import com.sx.core.utils.Sha;
import com.sx.core.utils.WxCommand;
import com.sx.core.utils.WxJsUtils;
import com.sx.core.utils.WxRequestInstance;
import com.sx.core.vo.Params;
import com.sx.wechat.security.AuthenticationHolder;
import com.sx.wechat.security.Principal;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Created by lihao on 16/12/21.
 */
@RestController
@RequestMapping("wechat/msg")
public class MsgController implements InitializingBean {

    Log logger= LogFactory.getLog(getClass());
    String token= PropertyUtils.getProperty("wx.server.token");
    String domain= PropertyUtils.getProperty("app.domain");
    String appId=PropertyUtils.getProperty("wx.appId");
    String secret=PropertyUtils.getProperty("wx.secret");
    String redirectUrl=PropertyUtils.getProperty("wechat.redirect.url");
    String teacher_redirectUrl=PropertyUtils.getProperty("teacher.redirect.url");
    String mobile_redirectUrl=PropertyUtils.getProperty("mobile.redirect.url");



    @Autowired
    SessionTemplate sessionTemplate;

    /**
     * 微信充值异步通知
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value = "openid",method = RequestMethod.GET)
    public ModelAndView openid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String openId= AuthenticationHolder.getOpenId(request);
        if(StringUtils.isEmpty(openId)){
            WxCommand wxCommand= WxJsUtils.getCommand(request,appId,secret);
            if(wxCommand==null){//如果没有获取到openid,可能的情况是直接在微信聊天里面打开首页，此时通过微信再次跳转
                try {
                    String wxRedirect="https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect";
                    response.sendRedirect(String.format(wxRedirect,appId,redirectUrl));
                } catch (IOException e) {
                }
                return null;
            }else{
                openId=wxCommand.getOpenId();
                AuthenticationHolder.saveOpenId(request,openId);
            }
        }
        if(StringUtils.isNotBlank(openId)){

            Information information=sessionTemplate.get(Information.class,"selectByOpenid",new Params().p("openid",openId));
            if(information!=null){
                Principal principal=new Principal();
                principal.setBindno(information.getSno());
                principal.setId(information.getId());
                principal.setType(information.getType());
                String sub_ject= JSON.toJSONString(principal);
                String token= JwtUtils.createJWT(information.getId(),sub_ject);
                if(StringUtils.equals(information.getType(),"1")){
                    response.sendRedirect(mobile_redirectUrl+"?token="+token);
                }else if(StringUtils.equals(information.getType(),"2")){
                    response.sendRedirect(teacher_redirectUrl+"?token="+token);
                }

            }else{
//                response.sendRedirect(index_redirectUrl+"?openid="+openId);
                ModelAndView modelAndView=new ModelAndView("mobileLogin");
                modelAndView.addObject("openid",openId);
                modelAndView.addObject("mobile_redirectUrl",mobile_redirectUrl);
                modelAndView.addObject("teacher_redirectUrl",teacher_redirectUrl);
                return modelAndView;

            }
        }
        return null;
    }
     /**
     * 微信充值异步通知
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value = "event",method = RequestMethod.GET)
    public String wx_bespoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        String[] strs=new String[]{token,timestamp,nonce};
        Arrays.sort(strs);
        String old = StringUtils.join(strs,"");
        logger.info("原串>>>"+old);
        String sign= Sha.sha(old);
        logger.info("签名后的>>>"+sign);
        logger.info("微信返回>>>"+signature);
        if(StringUtils.equals(sign,signature)){
            return echostr;
        }

        return echostr;
    }

    @RequestMapping(value = "event",method = RequestMethod.POST)
    public String wx_bespoke1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Element element=readWechat(request);
        String ToUserName=element.elementText("ToUserName");
        String FromUserName=element.elementText("FromUserName");
        String MsgType=element.elementText("MsgType");
        String Event=element.elementText("Event");
        String EventKey=element.elementText("EventKey");
//        if(StringUtils.equalsIgnoreCase("event",MsgType) && StringUtils.equalsIgnoreCase(Event,"CLICK")){
//            String domain=PropertyUtils.getProperty("app.domain");
//            String default_imgs=domain+"/images/placeholder.jpg";
//            if(StringUtils.equalsIgnoreCase(EventKey, Constants.M3_key_refer)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","点击填写疑问");
//                map.put("picurl",domain+"/images/m3_key_refer.jpg");
//                map.put("url",domain+"/api/h5/m3_refer?openid="+FromUserName);
//                list.add(map);
//                return replyArticleMsg(element,list);
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M3_key_cptj)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","更多产品推荐在这里");
//                map.put("picurl",domain+"/images/m3_key_refer.png");
//                map.put("url",domain+"/api/h5/m3_cptj?openid="+FromUserName);
//                list.add(map);
//                List<M3Cptj> m3Cptjs=sessionTemplate.list(M3Cptj.class,"selectTopList",null);
//                for(M3Cptj m3Cptj:m3Cptjs){
//                    map=new HashMap();
//                    map.put("title",m3Cptj.getTitle());
//                    map.put("picurl",StringUtils.defaultIfBlank(m3Cptj.getPicurl(),default_imgs));
//                    map.put("url",domain+"/api/h5/m3_cptj_detail?openid="+FromUserName+"&id="+m3Cptj.getId());
//                    list.add(map);
//                }
//                return replyArticleMsg(element,list);
//
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M3_key_xjtj)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","点击查看更多");
//                map.put("picurl",domain+"/images/m3_key_refer.png");
//                map.put("url",domain+"/api/h5/m3_xjtj?openid="+FromUserName);
//                list.add(map);
//                List<M3Xjtj> m3Cptjs=sessionTemplate.list(M3Xjtj.class,"selectTopList",null);
//                for(M3Xjtj m3Cptj:m3Cptjs){
//                    map=new HashMap();
//                    map.put("title",m3Cptj.getTitle());
//                    map.put("picurl",StringUtils.defaultIfBlank(m3Cptj.getPicurl(),default_imgs));
//                    map.put("url",domain+"/api/h5/m3_xjtj_detail?openid="+FromUserName+"&id="+m3Cptj.getId());
//                    list.add(map);
//                }
//                return replyArticleMsg(element,list);
//
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M2_key_fgtm)){//法规条目
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","法规条目展示");
////                map.put("picurl",domain+"/images/doglogo1.png");
////                map.put("url",domain+"/api/h5/m3_xjtj?openid="+FromUserName);
//                list.add(map);
//
//                List<Map<String,Object>> cats=M2_CAT.asList(domain,FromUserName);
//                list.addAll(cats);
//                return replyArticleMsg(element,list);
//
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M1_key_gzsx)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","点击查看更多");
//                map.put("picurl",domain+"/images/m1_key_gzsx.jpg");
//                map.put("url",domain+"/api/h5/m1_gzsx?openid="+FromUserName);
//                list.add(map);
//                List<M1Gzsx> m3Cptjs=sessionTemplate.list(M1Gzsx.class,"selectTopList",null);
//                for(M1Gzsx m3Cptj:m3Cptjs){
//                    map=new HashMap();
//                    map.put("title",m3Cptj.getTitle());
//                    map.put("picurl",StringUtils.defaultIfBlank(m3Cptj.getPicurl(),default_imgs));
//                    map.put("url",domain+"/api/h5/m1_gzsx_detail?openid="+FromUserName+"&id="+m3Cptj.getId());
//                    list.add(map);
//                }
//                return replyArticleMsg(element,list);
//
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M1_key_jxal)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","点击查看更多");
//                map.put("picurl",domain+"/images/m1_key_jxal.jpg");
//                map.put("url",domain+"/api/h5/m1_jxal?openid="+FromUserName);
//                list.add(map);
//                List<M1Jxal> m3Cptjs=sessionTemplate.list(M1Jxal.class,"selectTopList",null);
//                for(M1Jxal m3Cptj:m3Cptjs){
//                    map=new HashMap();
//                    map.put("title",m3Cptj.getTitle());
//                    map.put("picurl",StringUtils.defaultIfBlank(m3Cptj.getPicurl(),default_imgs));
//                    map.put("url",domain+"/api/h5/m1_jxal_detail?openid="+FromUserName+"&id="+m3Cptj.getId());
//                    list.add(map);
//                }
//                return replyArticleMsg(element,list);
//
//            }else if(StringUtils.equalsIgnoreCase(EventKey,Constants.M1_key_zsjs)){
//                List<Map<String,Object>> list=new ArrayList<>();
//                Map<String,Object> map=new HashMap();
//                map.put("title","知识竞赛");
//                map.put("picurl",domain+"/images/m1_key_zsjs.png");
////                map.put("url",domain+"/api/h5/m1_jxal?openid="+FromUserName);
//                list.add(map);
//
//                map=new HashMap();
//                map.put("title","海选答题");
//                map.put("picurl",domain+"/images/m1_zsjs_hx.jpg");
//                map.put("url",domain+"/api/h5/m1_zsjs?openid="+FromUserName+"&type=0");
//                list.add(map);
//
//                map=new HashMap();
//                map.put("title","竞赛答题");
//                map.put("picurl",domain+"/images/m1_zsjs_js.jpg");
//                map.put("url",domain+"/api/h5/m1_zsjs_login?openid="+FromUserName+"&type=1");
//                list.add(map);
//
//                return replyArticleMsg(element,list);
//
//            }
//
//
//
//
//        }
        return replyTextMsg(element,"欢迎关注公众号！！");
    }

    private String replyTextMsg(Element element,String Content){
        String ToUserName=element.elementText("ToUserName");
        String FromUserName=element.elementText("FromUserName");
        Document document= DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        root.addElement("ToUserName").addText(FromUserName);//此处要反向
        root.addElement("FromUserName").addText(ToUserName);
        root.addElement("CreateTime").addText(System.currentTimeMillis()/1000+"");
        root.addElement("MsgType").addText("text");
        root.addElement("Content").addText(Content);
        return root.asXML();
    }

    /**
     * <xml><ToUserName>< ![CDATA[toUser] ]></ToUserName><FromUserName>< ![CDATA[fromUser] ]></FromUserName>
     * <CreateTime>12345678</CreateTime><MsgType>< ![CDATA[news] ]></MsgType>
     * <ArticleCount>2</ArticleCount>
     * <Articles>
     *     <item>
     *         <Title>< ![CDATA[title1] ]></Title>
     *         <Description>< ![CDATA[description1] ]></Description>
     *         <PicUrl>< ![CDATA[picurl] ]></PicUrl>
     *         <Url>< ![CDATA[url] ]></Url>
     *     </item>
     *     <item><Title>< ![CDATA[title] ]></Title><Description>< ![CDATA[description] ]></Description><PicUrl>< ![CDATA[picurl] ]></PicUrl><Url>< ![CDATA[url] ]></Url></item>
     * </Articles></xml>
     * @param element
     * @param Content
     * @return
     */

    private String replyArticleMsg(Element element,List<Map<String,Object>> Content){
        String ToUserName=element.elementText("ToUserName");
        String FromUserName=element.elementText("FromUserName");
        Document document= DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        root.addElement("ToUserName").addText(FromUserName);
        root.addElement("FromUserName").addText(ToUserName);
        root.addElement("CreateTime").addText(System.currentTimeMillis()/1000+"");
        root.addElement("MsgType").addText("news");
        root.addElement("ArticleCount").addText(Content.size()+"");
        Element Articles=root.addElement("Articles");


        Content.forEach(map -> {
            Element item = Articles.addElement("item");
            item.addElement("Title").addText(ObjectUtils.toString(map.get("title")));
            item.addElement("Description").addText(ObjectUtils.toString(map.get("description")));
            item.addElement("PicUrl").addText(ObjectUtils.toString(map.get("picurl")));
            item.addElement("Url").addText(ObjectUtils.toString(map.get("url")));
        });
        return root.asXML();
    }
     private String replyUrl(Element element,List<Map<String,Object>> Content){
        String ToUserName=element.elementText("ToUserName");
        String FromUserName=element.elementText("FromUserName");
        Document document= DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        root.addElement("ToUserName").addText(FromUserName);
        root.addElement("FromUserName").addText(ToUserName);
        root.addElement("CreateTime").addText(System.currentTimeMillis()/1000+"");
        root.addElement("MsgType").addText("news");
        root.addElement("ArticleCount").addText(Content.size()+"");
        Element Articles=root.addElement("Articles");


        Content.forEach(map -> {
            Element item = Articles.addElement("item");
            item.addElement("Title").addText(ObjectUtils.toString(map.get("title")));
            item.addElement("Description").addText(ObjectUtils.toString(map.get("description")));
            item.addElement("PicUrl").addText(ObjectUtils.toString(map.get("picurl")));
            item.addElement("Url").addText(ObjectUtils.toString(map.get("url")));
        });
        return root.asXML();
    }



    private Element readWechat(HttpServletRequest request){
        String inputLine;
        StringBuffer stringBuffer = new StringBuffer();
        BufferedReader reader = null;
        Element element = null;
        try{
            reader = request.getReader();
            while ((inputLine = reader.readLine()) != null) {
                stringBuffer.append(inputLine);
            }
            if (logger.isInfoEnabled()) {
                logger.info("接受到微信事件消息:" + stringBuffer.toString());
            }
            element = WxJsUtils.parseXml(stringBuffer.toString());
        }catch (Exception e){
            logger.error("接受到微信事件消息异常",e);
        }finally {
            IOUtils.closeQuietly(reader);
        }
        return element;
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        WxRequestInstance.getInstance(appId,secret);
    }
}
